#!/usr/bin/python3
# -*- coding: utf-8 -*-

import logging
import os
import sys
import aiohttp
import jinja2
import aiohttp_jinja2
import datetime
from aiohttp import web

import settings
import db
from logger import set_logger
from middlewares import setup_middlewares
from route import routes


def size_filter(size):
    if size < 1024:
        return "%.3fb" % size
    if size < 1024 * 1024:
        return "%.3fK" % (size / 1024)
    if size < 1024 * 1024 * 1024:
        return "%.3fM" % (size / 1024 / 1024)
    if size < 1024 * 1024 * 1024 * 1024:
        return "%.3fM" % (size / 1024 / 1024 / 1024)


def status_filter(status):
    if status == '0':
        return "下载中...."
    if status == '1':
        return "下载完成"
    if status == '-1':
        return "下载已暂停"
    if status == '2':
        return "审核"
    if status == '3':
        return "公开"
    return ''


def blog_status_filter(status):
    if status == '-1':
        return "隐藏"


def range_slice(items, beg, end):
    if isinstance(items, list):
        return items[beg:end]
    return items


def datetime_filter(dt):
    if isinstance(dt, datetime.datetime):
        return dt.strftime("%Y-%m-%d %H:%M:%S")
    if isinstance(dt, str):
        return dt
    return None


def duration_filter(duration):
    duration = int(duration)
    return '00:%02d' % duration if duration < 60 else ('%02d:%02d' % (duration // 60, duration % 60) if duration < 3600 else ('%02d:%02d:%02d' % (duration // 3600, duration % 3600 // 60, duration % 3600 % 60)))


'''
获取指定模块的属性
'''


def get_module(module_name, name):
    mod = None
    n = module_name.rfind('.')
    if n == (-1):
        mod = __import__(module_name, globals(), locals())
    else:
        name = module_name[n+1:]
        mod = getattr(__import__(
            module_name[:n], globals(), locals(), [name]), name)
    return getattr(mod, name, None)


def add_routes(app):
    # 扫描以view_开头的模块
    # '''
    modules = [item if '.' not in item else item.split('.', 1)[0] for item in os.listdir(
        os.path.dirname(__file__)) if item.startswith('view_')]
    views = []
    for module_name in modules:
        prefix = get_module(module_name, 'module_name')
        if prefix:
            views.append(prefix)
        route = get_module(module_name, 'routes')
        if not route:
            continue
        logging.info('%smodule [%s] mapping%s' %
                     ('-' * 15, module_name, '-' * 15))
        for item in route:
            # 只打印RouteDef,避免StaticDef报错
            if isinstance(item, aiohttp.web_routedef.RouteDef):
                logging.info('%-4s %-25s -> %s' %
                             (item.method, item.path, item.handler.__name__))
        app.add_routes(route)
    # '''
    for key, value in routes.items():
        app.add_routes(value)
        views.append(key)
        logging.info('%smodule [%s] mapping%s' %
                     ('-' * 15, key, '-' * 15))
        for route in value:
            logging.info('%-4s %-25s -> %s' %
                         (route.method, route.path, route.handler.__name__))
    app.router.add_get('/', index, name='index')
    app['view_commons'] = {'views': views,
                           'static_url': settings.config['static']['url'],
                           'hlsurl': settings.config['hls']['hlsurl'],
                           'posterurl': settings.config['hls']['posterurl']}


@ aiohttp_jinja2.template('index.html')
async def index(request):
    data = request.app['view_commons']
    return data


def add_static_routes(app):
    app.router.add_static(
        '/static/', path=os.path.join(os.path.dirname(__file__), 'static'), name='static')
    logging.info('%sload static%s' % ('-' * 25, '-' * 25))
    for name, resource in app.router.named_resources().items():
        logging.info('%-30s -> %-25s' % (name, resource.canonical))


def init_jinja(app):
    filters = dict(status_filter=status_filter, size_filter=size_filter, datetime_filter=datetime_filter,
                   duration_filter=duration_filter, blog_status_filter=blog_status_filter, range_slice=range_slice)
    path = '%s/templates' % os.path.dirname(__file__)
    loader = jinja2.FileSystemLoader(path)
    env = jinja2.Environment(loader=loader)
    env.filters = dict(env.filters, **filters)
    app['__templating__'] = env
    aiohttp_jinja2.setup(app, loader=loader, filters=filters)


async def app_factory():
    settings.get_config()
    set_logger()
    db.init_db()
    app = web.Application()
    init_jinja(app)
    add_routes(app)
    setup_middlewares(app)
    return app


async def app_factory_local():
    set_logger()
    db.init_db('dev')
    app = web.Application()
    init_jinja(app)
    add_routes(app)
    add_static_routes(app)
    setup_middlewares(app)
    return app

if __name__ == '__main__':
    settings.get_config('dev')
    if len(sys.argv) >= 2:
        conf = {}
        for item in sys.argv[1:]:
            if '=' in item:
                item = item.split('=')
                conf[item[0]] = item[1]
        settings.set_config(conf)
    web.run_app(app_factory_local(),
                host=settings.config['host'], port=settings.config['port'])
    # web.run_app(app_factory_local())
